﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.IO;

namespace MSL.Utility.Format
{
    /// <summary>
    /// 常用验证方法类
    /// </summary>
    public class Verify
    {
        /// <summary>
        /// 大写日期
        /// </summary>
        public const string UPPERDATE = @"(一九|二[〇○ＯO\d]|零○)[一二三四五六七八九十零○OＯ〇\d]{1,2}(年|.年)[一二三四五六七八九十零○〇OＯ](月|.月)[一二三四五六七八九十零○〇OＯ](日|.日|..日)";
        /// <summary>
        /// 小写日期
        /// </summary>
        public const string LOWERDATE = @"(19|20|１９|２０)[\dＯ１２３４５６７８９]{2}(年|.年)[\d１２３４５６７８９]{1,2}(月|.月)[\d１２３４５６７８９]{1,2}(日|.日|..日)";
        /// <summary>
        /// 日期时间正则
        /// </summary>
        public const string DATE = @"(((19|20|)\d\d(-|年|\.|/)(0[1-9]|1[012]|[1-9])(-|月|\.|/)([012][0-9]|3[01]|[1-9]|)(日\s|\s|日)?)|(([012345][0-9]|[1-9]):([012345][0-9]|[1-9]|)))|((19|20|)\d\d(-|年|\.)(0[1-9]|1[012]|[1-9])(-|月|\.)([012][0-9]|3[01]|[1-9]|))|((0[1-9]|1[012]|[1-9])(-|\.|\|/)([012][0-9]|3[01]|[1-9]|)(-|\.|\|/)(19|20|)\d\d|((19|20)\d\d(0[1-9]|1[012]|[1-9])([012][0-9]|3[01]|[1-9])))";


        #region 判断文件流是否为UTF8字符集

        /// <summary>
        /// 判断文件流是否为UTF8字符集
        /// </summary>
        /// <param name="sbInputStream">文件流</param>
        /// <returns>判断结果</returns>
        private static bool IsUTF8(FileStream sbInputStream)
        {
            int i;
            byte cOctets;  // octets to go in this UTF-8 encoded character 
            byte chr;
            bool bAllAscii = true;
            long iLen = sbInputStream.Length;

            cOctets = 0;
            for (i = 0; i < iLen; i++)
            {
                chr = (byte)sbInputStream.ReadByte();

                if ((chr & 0x80) != 0) bAllAscii = false;

                if (cOctets == 0)
                {
                    if (chr >= 0x80)
                    {
                        do
                        {
                            chr <<= 1;
                            cOctets++;
                        }
                        while ((chr & 0x80) != 0);

                        cOctets--;
                        if (cOctets == 0) return false;
                    }
                }
                else
                {
                    if ((chr & 0xC0) != 0x80)
                    {
                        return false;
                    }
                    cOctets--;
                }
            }

            if (cOctets > 0)
            {
                return false;
            }

            if (bAllAscii)
            {
                return false;
            }

            return true;

        }
        #endregion

        #region 外部参数数据验证
        /// <summary>
        ///  外部参数数据验证 不能包含 "'", ";", "'", "--", "*", "\\", "{", "}", "(", ")", "SELECT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP", "EXEC", "INSERT", "AND", "COUNT", "MID", "MASTER", "TRUNCATE", "CHAR", "DECLARE", "SYSOBJECTS", "VARCHAR" 
        /// </summary>
        /// <param name="args">类型 object[] </param>
        /// <returns>bool</returns>
        public static bool ValiDate(params object[] args)
        {
            String[] immit = { "'", ";", "'", "--", "*", "\\", "{", "}", "(", ")", "SELECT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP", "EXEC", "INSERT", "AND", "COUNT", "MID", "MASTER", "TRUNCATE", "CHAR", "DECLARE", "SYSOBJECTS", "VARCHAR" };

            foreach (object arg in args)
            {
                if (arg is string)
                {
                    string str = arg.ToString().ToUpper();

                    for (int i = 0; i < immit.Length; i++)
                    {
                        int t = str.IndexOf(immit[i]);

                        if (t > -1)
                        {
                            return true;
                        }
                    }
                }
                else if (arg is ICollection)//如果是一个集合,则检查集合内元素是否字符串,是字符串,就进行检查       
                {
                    foreach (object obj in (ICollection)arg)
                    {
                        if (obj is string)
                        {
                            string str = arg.ToString().ToUpper();

                            for (int i = 0; i < immit.Length; i++)
                            {
                                int t = str.IndexOf(immit[i]);

                                if (t > -1)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            return false;
        }

        //public static string SQLformat(string SqlStr)
        //{
        //    //if (SqlStr.Length>0)
        //    //{
        //    //     SqlStr = SqlStr.ToLower();
        //    //}    

        //    if (SqlStr.Length > 0)
        //    {
        //        string SqlStrnot = "and|exec|insert|select|delete|update|count|*|chr|mid|master|truncate|char|declare|=|or|sysobjects|varchar|set";

        //        string[] anySqlStr = SqlStrnot.Split('|');
        //        foreach (string ss in anySqlStr)
        //        {
        //            if (SqlStr.ToLower().IndexOf(ss) >= 0)
        //            {
        //                SqlStr = SqlStr.ToLower().Replace(ss, "");
        //            }
        //        }
        //    }
        //    return SqlStr;
        //}
        #endregion

        #region 判断文件名是否为浏览器可以直接显示的图片文件名

        /// <summary>
        /// 判断文件名是否为浏览器可以直接显示的图片文件名
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否可以直接显示</returns>
        public static bool IsImgFilename(string filename)
        {
            filename = filename.Trim();
            if (filename.EndsWith(".") || filename.IndexOf(".") == -1)
            {
                return false;
            }
            string extname = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
            return (extname == "jpg" || extname == "jpeg" || extname == "png" || extname == "bmp" || extname == "gif");
        }
        #endregion

        #region 检测是否符合email格式

        /// <summary>
        /// 检测是否符合email格式
        /// </summary>
        /// <param name="strEmail">要判断的email字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsEmail(string strEmail)
        {
            //^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
            return Regex.IsMatch(strEmail, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        #endregion

        #region 检测是否是正确的Url
        /// <summary>
        /// 检测是否是正确的Url
        /// </summary>
        /// <param name="strUrl">要验证的Url</param>
        /// <returns>判断结果</returns>
        public static bool IsURL(string strUrl)
        {
            return Regex.IsMatch(strUrl, @"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$");
        }
        #endregion

        #region 检测是否是Int
        /// <summary>
        /// 判断字符串是否为Int类型的
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool IsInt(string val)
        {
            return Regex.IsMatch(val, @"^[1-9]\d*\.?[0]*$");
        }
        #endregion

        #region 校验身份证格式方法(支持18位数字或17位数字加X或者x)
        /// <summary>
        /// 身份证号
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsIDCard(string input)
        {
            return Regex.IsMatch(input, @"\d{18}|\d{15}||(\d17}[Xx])$");
        }
        #endregion

        #region 检测邮编
        /// <summary>
        /// 检测邮编
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsZip(string input)
        {
            return Regex.IsMatch(input, @"\d{6}");
        }
        #endregion

        #region 检测日期
        /// <summary>
        /// 检测日期
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDate(string input)
        {
            return Regex.IsMatch(input, DATE);
        }
        #endregion

        #region 检测数值
        /// <summary>
        /// 检测是否为
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNumber(string input)
        {
            return Regex.IsMatch(input, @"^-?(0|\d+)(\.\d+)?$");
        }
        /// <summary>
        /// 检测字符串是否全为正整数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNum(string input)
        {
            bool blResult = true;//默认状态下是数字

            if ((input + "").Length == 0)
            {
                return false;
            }
            else
            {
                foreach (char Char in input)
                {
                    if (!char.IsNumber(Char))
                    {
                        blResult = false;
                        break;
                    }
                }
                if (blResult)
                {
                    if (int.Parse(input) == 0)
                        blResult = false;
                }
            }
            return blResult;
        }

        /// <summary>
        /// 检测字符串是否全为数字型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDouble(string input)
        {
            bool blResult = true;//默认状态下是数字
            if ((input + "").Length == 0)
            {
                return false;
            }
            else
            {
                foreach (char Char in input)
                {
                    if (!char.IsNumber(Char) && Char.ToString() != "-")
                    {
                        blResult = false;
                        break;
                    }
                }
            }
            return blResult;
        }

        #endregion

        #region 检测汉字

        public static bool IsChinese(string input)
        {
            return Regex.IsMatch(input, @"(^[\u4e00-\u9fa5]{1,}$)");
        }
        #endregion

        #region 检测年龄
        /// <summary>
        ///  /// <summary>
        /// 年龄(输入0时只能输入一位,输入多位时第一位不能是0)。
        /// </summary>
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsAge(string input)
        {
            return Regex.IsMatch(input, @"(^(0|[1-9][0-9]*){1,3}$)");
        }
        #endregion

        #region 检测电话号码
        /// <summary>
        /// 电话号码(支持手机号码,3-4位区号,7-8位直播号码,1－4位分机号
        /// </summary>
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsCallNumber(string input)
        {
            return Regex.IsMatch(input, @"(([0-9]{11})|^(([0-9]{7,8})|([0-9]{4}|[0-9]{3})-([0-9]{7,8})|([0-9]{4}|[0-9]{3})-([0-9]{7,8})-([0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1})|([0-9]{7,8})-([0-9]{4}|[0-9]{3}|[0-9]{2}|[0-9]{1}))$)");
        }
        #endregion

        #region 检测天数（只能输入自然数）
        /// <summary>
        /// 检测天数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDay(string input)
        {
            return Regex.IsMatch(input, @"^[1-9][0-9]*$");
        }
        #endregion

        #region 验证用户名
        /// <summary>
        /// 验证用户名
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsName(string input)
        {
            return Regex.IsMatch(input, @"^[a-zA-Z][a-zA-Z0-9]{3,19}$");
        }
        #endregion

        #region 验证手机
        /// <summary>
        /// 验证手机
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsMobilePhone(string input)
        {
            return Regex.IsMatch(input, @"^(13|15)\\d{9}$");
        }
        #endregion

        #region  验证qq
        /// <summary>
        /// 验证qq
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool Isqq(string input)
        {
            return Regex.IsMatch(input, @"^[1-9][0-9]{4,8}$");

        }
        #endregion

        #region 验证价钱
        /// <summary>
        /// 验证价钱
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsMoney(string input)
        {
            return Regex.IsMatch(input, @"^\\d+(\\.\\d\\d)?$");
        }
        #endregion

        #region 检测客户的输入中是否有危险字符串
        /// <summary>
        /// 检测客户输入的字符串是否有效,并将原始字符串修改为有效字符串或空字符串。
        /// 当检测到客户的输入中有攻击性危险字符串,则返回false,有效返回true。
        /// </summary>
        /// <param name="input">要检测的字符串</param>
        public static bool IsValidInput(ref string input)
        {
            try
            {
                if (String.IsNullOrEmpty(input))
                {
                    return true;
                }
                else
                {
                    //替换单引号
                    input = input.Replace("'", "''").Trim();

                    //检测攻击性危险字符串
                    string testString = "and |or |exec |insert |select |delete |update |count |chr |mid |master |truncate |char |declare ";
                    string[] testArray = testString.Split('|');
                    foreach (string testStr in testArray)
                    {
                        if (input.ToLower().IndexOf(testStr) != -1)
                        {
                            //检测到攻击字符串,清空传入的值
                            input = "";
                            return false;
                        }
                    }

                    //未检测到攻击字符串
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion
    }
}
